import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class Main {
	
	public static void main(String[] args) {		
		String diretorioComArquivos = System.getProperty("user.dir") + System.getProperty("file.separator") + "ArquivosParaTeste" + System.getProperty("file.separator");
		String diretorioComArquivosErrados = diretorioComArquivos + "AnalisesFalhas" + System.getProperty("file.separator");
		List<String> arquivosParaTeste = new ArrayList<String>();
		List<String> listaDeErros = new ArrayList<String>();
		
		//Analises Semanticas Falhas
		/*arquivosParaTeste.add(diretorioComArquivosErrados + "funcaoNaoDefinida.py");
		arquivosParaTeste.add(diretorioComArquivosErrados + "variavelNaoDefinida.py");
		arquivosParaTeste.add(diretorioComArquivosErrados + "sequenciadorForaDoLoop.py");
		arquivosParaTeste.add(diretorioComArquivosErrados + "escopoReturn.py");

		//arquivosParaTeste.add(diretorioComArquivosErrados + "funcaoNaoDefinida.py");
		//arquivosParaTeste.add(diretorioComArquivosErrados + "variavelNaoDefinida.py");
		//arquivosParaTeste.add(diretorioComArquivosErrados + "sequenciadorForaDoLoop.py");
		//arquivosParaTeste.add(diretorioComArquivosErrados + "escopoReturn.py");
		//arquivosParaTeste.add(diretorioComArquivosErrados + "numeroParametros.py");

		arquivosParaTeste.add(diretorioComArquivos + "operacoesAritmeticas.py");
		arquivosParaTeste.add(diretorioComArquivos + "comandosCondicionais.py"); 		
		arquivosParaTeste.add(diretorioComArquivos + "definicaoFuncao.py"); */
		arquivosParaTeste.add(diretorioComArquivos + "comandosAtribuicao.py");

		//arquivosParaTeste.add(diretorioComArquivos + "operacoesAritmeticas.py");
		//arquivosParaTeste.add(diretorioComArquivos + "while.py");
		//arquivosParaTeste.add(diretorioComArquivos + "comandosCondicionais.py");
		//arquivosParaTeste.add(diretorioComArquivos + "definicaoFuncao.py");

		
		for(String arquivo : arquivosParaTeste) {
			System.out.println("==========================");
			System.out.println("Analise do arquivo: " + arquivo);			
			try {
				AnalisadorLexico analisadorLexico = new AnalisadorLexico(new FileReader(arquivo));
				analisadorLexico.setFileName(arquivo);
				AnalisadorSintaticoCup analisadorSintatico = new AnalisadorSintaticoCup(analisadorLexico);
				ParseNode raiz = (ParseNode) analisadorSintatico.parse().value;
				String sep = System.getProperty("line.separator");
				StringBuilder sb = new StringBuilder();
				sb.append("digraph g {");
				sb.append(sep);
				sb.append("node [shape=ellipse]");
				sb.append(sep);
				sb.append("struct00 [label=\"Programa Python\"];");
				sb.append(sep);
				raiz.imprimeArvore("struct00", new Random(), sb);
				sb.append("}");
				sb.toString().replaceAll("\n", "EOF");
				FileUtils.fileOutputStream("arvore.gv", false, sb.toString().replaceAll(sep +"\"", "NEWLINE\"").replaceAll("    ","INDENT"));
				System.out.println("Resultado: OK!");
				
				System.out.println("------");
				System.out.println("Geracao de codigo...");
				GeradorUtil gerador = GeradorUtil.getInstance();
				gerador.setNomeArquivo(arquivo + ".asm");
				//Inicia o arquivo sem nada.
				FileUtils.fileOutputStream(arquivo + ".asm", false, "");
				gerador.geraCodigo(raiz);
				System.out.println("Resultado: OK!");
				
			}
			
			catch (FileNotFoundException e) {
				System.out.println("Arquivo " + arquivo + " nao encontrado");
			} catch (Exception e) {
				System.out.println("Erro de analise semantica: " + e.getMessage() + "\n");
				continue;
			} catch (Error e) {
				listaDeErros.add(e.getMessage() + " no arquivo " + arquivo);
				System.out.print(" Erro\n");
				continue;
			}	
			
		}
		
		if (!listaDeErros.isEmpty()) {
			System.out.println(" \n\n############################################################# ");
			System.out.println("          Relatorio de Erros          ");
			System.out.println("#############################################################\n ");
			for(String erro: listaDeErros) {
				System.out.println(erro);
			}	
		}
	
	}

}
